#
#   MenuSystem.py
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; version 2 of the License.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   Copyright
#   Author: Salvatore S. Gionfriddo
#   Contributors: Nicholas F. Hoover
#   Created: 2007.07.24
#   Last Modified: 2007.11.05
#

import hud, pygame, sys, Messages, EventHandler
from Options import Options

class Menu:
    
    (ITEM_NAME, ITEM_FUNCTION, ITEM_CHOICES, ITEM_SELECTION) = range(4)

    Y_OFFSET_PER_LINE = 50

    MENU_INSTRUCTIONS = ["Press Up or Down to select menu items.",
                         "Press Left or Right to change the option.",
                         "Press Enter to select the item."]
    
    def __init__(self, screen, items, splash):
        self.menuItems = items
        self.MENU_SIZE = len(self.menuItems)
        self.screen = screen
        self.x = 200
        self.y = 200
        self.continue_display = True
        self.splash = splash
        self.menuSelection = 0

        self.labels = []
        yOffset = 0
        for menuItem in self.menuItems:
            text = menuItem[self.ITEM_NAME]
            if menuItem[self.ITEM_CHOICES]:
                text += ": "
                index = menuItem[self.ITEM_SELECTION]
                text += menuItem[self.ITEM_CHOICES][index]
            self.labels.append(hud.label(self.screen,(self.x,self.y+yOffset),text))
            yOffset += self.Y_OFFSET_PER_LINE
            
        for label in self.labels:
            label.setSize(20)
            #label.setBackColor((255,255,255))

        self.menu_instructions = hud.text_box(self.screen, (self.x+50, self.y-100), self.MENU_INSTRUCTIONS)

        self.updateHighlight()

    def draw(self):
        self.screen.blit(self.splash,(0,0))
        self.tintScreen()
        
        bbar = pygame.Surface((490, len(self.labels) * 50 + 20))
        bbar = bbar.convert()
        bbar.fill((40,20,0))
        bbar.set_alpha(220)
        self.screen.blit(bbar, (self.x-30,self.y-30))
        
        bar = pygame.Surface((470, len(self.labels) * 50))
        bar = bar.convert()
        bar.fill((100,200,100))
        bar.set_alpha(180)
        self.screen.blit(bar, (self.x-20,self.y-20))

        for label in self.labels:
            label.draw()
            
        self.menu_instructions.setAlpha(240)
        self.menu_instructions.draw()

    def incMenuSelection(self):
        self.menuSelection += 1
        if self.menuSelection >= self.MENU_SIZE: self.menuSelection = 0
        self.updateHighlight()
        
    def decMenuSelection(self):
        self.menuSelection -=1
        if self.menuSelection < 0: self.menuSelection = self.MENU_SIZE - 1
        self.updateHighlight()
        
    def updateHighlight(self):
        for i in range(self.MENU_SIZE):
            if i == self.menuSelection:
                self.labels[i].setTextColor((255,255,255))
                self.labels[i].setAlpha(10)
            else:
                self.labels[i].setTextColor((0,0,0))
                self.labels[i].setAlpha(200)
                
    def decOption(self):
        if self.menuItems[self.menuSelection][self.ITEM_CHOICES]:
            self.menuItems[self.menuSelection][self.ITEM_SELECTION] -= 1
            if self.menuItems[self.menuSelection][self.ITEM_SELECTION] < 0:
                self.menuItems[self.menuSelection][self.ITEM_SELECTION] = 0
            self.updateItemSelection(self.menuItems[self.menuSelection])
            
    def incOption(self):
        if self.menuItems[self.menuSelection][self.ITEM_CHOICES]:
            self.menuItems[self.menuSelection][self.ITEM_SELECTION] += 1
            if self.menuItems[self.menuSelection][self.ITEM_SELECTION] >= len(self.menuItems[self.menuSelection][self.ITEM_CHOICES]):
                self.menuItems[self.menuSelection][self.ITEM_SELECTION] = len(self.menuItems[self.menuSelection][self.ITEM_CHOICES]) - 1
            self.updateItemSelection(self.menuItems[self.menuSelection])
            
    def updateItemSelection(self, menuItem):
        text = menuItem[self.ITEM_NAME] + ": "
        text += menuItem[self.ITEM_CHOICES][menuItem[self.ITEM_SELECTION]]
        self.labels[self.menuSelection].setValue(text)
        
    def display(self):
        self.continue_display = True
        while self.continue_display:

            self.draw()
            pygame.display.flip()
            event = pygame.event.wait()
            if event.type == pygame.QUIT:
                sys.exit()
            
            elif event.type == pygame.KEYDOWN:
                key = event.key
                if key == pygame.K_ESCAPE: # EXIT GAME
                    sys.exit()
                elif key == pygame.K_DOWN: # SELECT NEXT ITEM
                    self.incMenuSelection()
                elif key == pygame.K_UP: # SELECT PREVIOUS ITEM
                    self.decMenuSelection()
                elif key == pygame.K_LEFT: # CHANGE OPTION
                    self.decOption()
                elif key == pygame.K_RIGHT: # CHANGE OPTION
                    self.incOption()
                elif key == pygame.K_RETURN: # SELECT ITEM
                    if self.menuItems[self.menuSelection][self.ITEM_FUNCTION]:
                        self.menuItems[self.menuSelection][self.ITEM_FUNCTION]()
                        
    def stop(self):
        self.continue_display = False

    def tintScreen(self):
        tint = pygame.Surface(self.screen.get_size())
        tint.fill((0,0,0))
        tint.set_alpha(40)
        self.screen.blit(tint,(0,0))

                       
class MenuSystem:
    (MAIN, OPTIONS) = range(2)
    def __init__(self, screen, gameOptions, splash, setMission = None, highScores = {}):
        self.menus = range(2)
        self.setMission = setMission
        self.screen = screen
        self.current_menu = self.MAIN
        missions = ["INTRO", "BEGINNER","CHALLENGE", "SOUL COLLECTOR", "HAPPY HOLIDAYS", "EXPERT"]
        scoreTexts = []
        self.gameOptions = gameOptions
        for mission in missions:
            scoreTexts.append(mission + " - " + str(highScores[mission]))
        
        main_menu_items = [
            ["PLAY", self.play, None, 0],
            ["MISSION",      self.play, missions, 0],
            ["OPTIONS",      (lambda: self.setMenu(self.OPTIONS)), None, 0],
            ["HIGH SCORES",  None, scoreTexts, 0],
            ["INSTRUCTIONS", self.drawInstructions, None, 0],
            ["QUIT",         sys.exit, None, 0]]

        #check options status
        if self.gameOptions.VIDEO['FULLSCREEN']: fullscreen_status = 0
        else: fullscreen_status = 1
        if self.gameOptions.SOUND['MUSIC_ON']:music_status = 0
        else: music_status = 1
        
        options_menu_items = [["Fullscreen", self.setFullscreenOption, ["On", "Off"], fullscreen_status],
                                ["Music", self.setMusicOption, ["On", "Off"],0,],
                                ["SAVE", self.saveOptions, None, 0],
                                ["BACK", self.back, None, 0]]
        
        self.menus[self.MAIN] = Menu(screen, main_menu_items, splash)
        self.menus[self.OPTIONS] = Menu(screen, options_menu_items, splash)
        
    def display(self):
        self.menus[self.current_menu].display()
        
    def back(self):
        self.play()
        self.setMenu(self.MAIN)
        
    def play(self):
        if self.setMission:
            #SMYMADHAZZZZZZZZZZZZXXXXXXXXXXX
            self.setMission(self.menus[self.MAIN].menuItems[1][2][self.menus[self.MAIN].menuItems[1][3]])
        self.menus[self.current_menu].stop()
        
    def setMenu(self, menu):
        self.current_menu = menu
        self.display()
        
    def drawInstructions(self):
        self.tintScreen()
        Messages.printInstructions(self.screen)
        pygame.display.flip()
        EventHandler.waitForKeyOrQuit(Options.CONTROLS['ENTER'])

    def tintScreen(self):
        tint = pygame.Surface(self.screen.get_size())
        tint.fill((0,0,0))
        tint.set_alpha(40)
        self.screen.blit(tint,(0,0))

##########################
# OPTIONS MENU FUNCTIONS #
##########################
    def setFullscreenOption(self):
        if self.menus[self.OPTIONS].menuItems[0][self.menus[self.OPTIONS].ITEM_SELECTION] == 0:
            self.gameOptions.setFullscreen(True)
        elif self.menus[self.OPTIONS].menuItems[0][self.menus[self.OPTIONS].ITEM_SELECTION] == 1:
            self.gameOptions.setFullscreen(False)
            
    def setMusicOption(self):
        if self.menus[self.OPTIONS].menuItems[1][self.menus[self.OPTIONS].ITEM_SELECTION] == 0:
            self.gameOptions.setMusicOn(True)
        elif self.menus[self.OPTIONS].menuItems[1][self.menus[self.OPTIONS].ITEM_SELECTION] == 1:
            self.gameOptions.setMusicOn(False)
            
    def saveOptions(self):
        self.setFullscreenOption()
        self.setMusicOption()
        self.gameOptions.writeOptionsFile()
        
    def back(self):
        self.menus[self.OPTIONS].stop()
        self.setMenu(self.MAIN)
